package cn.lg.soar.general.manager;

import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.general.api.enums.FileStorageStatusEnum;
import cn.lg.soar.general.entity.FileStorage;
import cn.lg.soar.general.s3.FileTemplate;
import cn.lg.soar.general.service.IFileStorageService;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.Duration;
import java.util.Objects;
import java.util.function.Function;

/**
 * @author luguoxiang 469599794@qq.com
 * @Date: 2024/3/1 21:24
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class FileTemplateManager {

    @Autowired
    private IFileStorageService storageService;

    private static final Cache<Long, FileTemplate> CACHE = Caffeine.newBuilder()
            .initialCapacity(16)
            .maximumSize(64)
            .expireAfterWrite(Duration.ofSeconds(120))
            .build();

    /**
     * 获取上传模板（有缓存）
     * @param fileStorage
     * @return
     */
    public FileTemplate getTemplate(FileStorage fileStorage) {
        AssertUtil.notNull(fileStorage, "未找到文件仓库");
        AssertUtil.isFalse(FileStorageStatusEnum.disabled.equals(fileStorage.getStatus()), "仓库已禁用");
        Long id = fileStorage.getId();
        Function<Long, FileTemplate> function = (k) -> FileTemplate.create(fileStorage);
        FileTemplate uploadTemplate = CACHE.get(id, function);
        if (Objects.equals(fileStorage.getVersion(), uploadTemplate.getConfigVersion())) {
            return uploadTemplate;
        }
        // 配置版本不一致重新生成
        uploadTemplate = function.apply(id);
        CACHE.invalidate(id);
        CACHE.put(id, uploadTemplate);
        return uploadTemplate;
    }

    /**
     * 获取上传模板（有缓存）
     * @param id
     * @return
     */
    public FileTemplate getTemplate(Long id) {
        return getTemplate(
                storageService.getById(id)
        );
    }

    /**
     * 获取默认上传模板（有缓存）
     * @return
     */
    public FileTemplate getTemplateByDetaulted() {
        return getTemplate(
                storageService.getDefaulted()
        );
    }

    /**
     * 删除上传模板缓存
     * @param id
     */
    public void removeTemplate(Object id) {
        FileTemplate template = CACHE.getIfPresent(id);
        if (template != null) {
            CACHE.invalidate(id);
            template.disconnect();
        }
    }

}
